// dao/mysql/user_post_history.go
package mysql

import (
	"bluebell/models"
	"fmt" // 导入 fmt 包用于字符串拼接
	"github.com/jmoiron/sqlx"
	"go.uber.org/zap"
	"strings"
)

// CreateOrUpdateUserPostHistory 记录或更新用户帖子观看历史
func CreateOrUpdateUserPostHistory(history *models.UserPostHistory) error {
	// 尝试插入，如果冲突（user_id, post_id 唯一约束），则更新 view_time
	sqlStr := `
        INSERT INTO user_post_history (user_id, post_id, view_time)
        VALUES (?, ?, ?)
        ON DUPLICATE KEY UPDATE view_time = VALUES(view_time)
    `
	_, err := db.Exec(sqlStr, history.UserID, history.PostID, history.ViewTime)
	if err != nil {
		zap.L().Error("create or update user post history failed", zap.Error(err))
		return err
	}
	return nil
}

// GetUserPostHistoryList 获取用户观看历史列表
func GetUserPostHistoryList(userID, page, size int64) ([]*models.UserPostHistory, error) {
	offset := (page - 1) * size
	if offset < 0 {
		offset = 0
	}

	sqlStr := `
        SELECT 
            history_id, 
            user_id, 
            post_id, 
            view_time
        FROM user_post_history
        WHERE user_id = ?
        ORDER BY view_time DESC
        LIMIT ? OFFSET ?
    `

	var histories []*models.UserPostHistory
	err := db.Select(&histories, sqlStr, userID, size, offset)
	if err != nil {
		return nil, err
	}
	return histories, nil
}

func GetPostsPreviewByIDs(postIDs []int64) (map[int64]*struct {
	Title   string
	Content string
}, error) {
	if len(postIDs) == 0 {
		return nil, nil
	}

	// 构建IN查询
	query, args, err := sqlx.In(`
        SELECT 
            post_id,
            title,
            SUBSTRING(content, 1, 20) AS content
        FROM post 
        WHERE post_id IN (?)
    `, postIDs)
	if err != nil {
		return nil, err
	}

	var posts []struct {
		PostID  int64  `db:"post_id"`
		Title   string `db:"title"`
		Content string `db:"content"`
	}

	err = db.Select(&posts, query, args...)
	if err != nil {
		return nil, err
	}

	result := make(map[int64]*struct {
		Title   string
		Content string
	})
	for _, p := range posts {
		result[p.PostID] = &struct {
			Title   string
			Content string
		}{
			Title:   p.Title,
			Content: p.Content,
		}
	}
	return result, nil
}

// GetPostsByHistoryIDs 根据历史记录中的 PostID 获取帖子详情
func GetPostsByHistoryIDs(postIDs []int64) ([]*models.Post, error) {
	if len(postIDs) == 0 {
		return nil, nil // 如果没有ID，直接返回空列表
	}

	// 构建 IN 子句的占位符字符串
	placeholders := make([]string, len(postIDs))
	args := make([]interface{}, len(postIDs))
	for i, id := range postIDs {
		placeholders[i] = "?"
		args[i] = id
	}
	inClause := strings.Join(placeholders, ",")

	sqlStr := fmt.Sprintf(`SELECT post_id, author_id, community_id, status, title, content, create_time FROM post WHERE post_id IN (%s)`, inClause)

	var posts []*models.Post
	err := db.Select(&posts, sqlStr, args...)
	if err != nil {
		zap.L().Error("GetPostsByHistoryIDs failed", zap.Error(err))
		return nil, err
	}
	return posts, nil
}

// GetCommunityNamesByIDs 根据社区ID获取社区名称
func GetCommunityNamesByIDs(communityIDs []int64) (map[int64]string, error) {
	if len(communityIDs) == 0 {
		return make(map[int64]string), nil // 如果没有ID，返回空map
	}

	placeholders := make([]string, len(communityIDs))
	args := make([]interface{}, len(communityIDs))
	for i, id := range communityIDs {
		placeholders[i] = "?"
		args[i] = id
	}
	inClause := strings.Join(placeholders, ",")

	sqlStr := fmt.Sprintf("SELECT community_id, community_name FROM community WHERE community_id IN (%s)", inClause)

	var communities []struct {
		CommunityID   int64  `db:"community_id"`
		CommunityName string `db:"community_name"`
	}
	err := db.Select(&communities, sqlStr, args...)
	if err != nil {
		zap.L().Error("GetCommunityNamesByIDs failed", zap.Error(err))
		return nil, err
	}
	communityMap := make(map[int64]string)
	for _, c := range communities {
		communityMap[c.CommunityID] = c.CommunityName
	}
	return communityMap, nil
}

// GetUsernamesByIDs 根据用户ID获取用户名
func GetUsernamesByIDs(userIDs []int64) (map[int64]string, error) {
	if len(userIDs) == 0 {
		return make(map[int64]string), nil // 如果没有ID，返回空map
	}

	placeholders := make([]string, len(userIDs))
	args := make([]interface{}, len(userIDs))
	for i, id := range userIDs {
		placeholders[i] = "?"
		args[i] = id
	}
	inClause := strings.Join(placeholders, ",")

	sqlStr := fmt.Sprintf("SELECT user_id, username FROM user WHERE user_id IN (%s)", inClause)

	var users []struct {
		UserID   int64  `db:"user_id"`
		Username string `db:"username"`
	}
	err := db.Select(&users, sqlStr, args...)
	if err != nil {
		zap.L().Error("GetUsernamesByIDs failed", zap.Error(err))
		return nil, err
	}
	userMap := make(map[int64]string)
	for _, u := range users {
		userMap[u.UserID] = u.Username
	}
	return userMap, nil
}

// GetUserPostHistoryCount 获取用户观看历史的总数
func GetUserPostHistoryCount(userID int64) (int64, error) {
	var count int64
	sqlStr := `SELECT count(history_id) FROM user_post_history WHERE user_id = ?`
	err := db.Get(&count, sqlStr, userID)
	if err != nil {
		zap.L().Error("get user post history count failed", zap.Error(err))
		return 0, err
	}
	return count, nil
}

// CheckHistoryOwnership 检查历史记录是否属于该用户
func CheckHistoryOwnership(historyID, userID int64) (bool, error) {
	var count int
	sqlStr := `SELECT COUNT(*) FROM user_post_history 
               WHERE history_id = ? AND user_id = ?`
	err := db.Get(&count, sqlStr, historyID, userID)
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// DeleteHistoryByID 删除单条历史记录
func DeleteHistoryByID(historyID int64) error {
	sqlStr := `DELETE FROM user_post_history WHERE history_id = ?`
	_, err := db.Exec(sqlStr, historyID)
	return err
}

// DeleteAllHistoryForUser 删除用户所有历史记录
func DeleteAllHistoryForUser(userID int64) error {
	sqlStr := `DELETE FROM user_post_history WHERE user_id = ?`
	_, err := db.Exec(sqlStr, userID)
	return err
}
